﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ECare.BUS.Data;
using ECare.Database;

namespace ECare.BUS
{
    public class PlanHelper
    {

        public static int CreatePlan(PlanInfo planinfo)
        {
            using (var context = new Entities())
            {
                var newplan = new plan();
                newplan.formula_id = planinfo.formula_id;
                newplan.plan_date = planinfo.plan_date;
                newplan.plan_times = planinfo.plan_times;

                newplan.plan_create_by = ApplicationData.CurrentUserInfo.UserId;
                newplan.plan_create_time = DateTime.Now;

                newplan.plan_update_time = DateTime.Now;
                newplan.plan_update_by = ApplicationData.CurrentUserInfo.UserId;
                newplan.plan_status = (int)PlanStatus.draft;

                newplan.plan_IsGenerateResources = false;
                context.plans.AddObject(newplan);

                context.SaveChanges();
                return newplan.plan_id;
                // return true;
            }
        }

        public static List<PlanInfo> GetPlans(string wherestr, bool isout = false)
        {
            using (var context = new Entities())
            {
                var res = new List<PlanInfo>();

                List<plan> plans = new List<plan>();
                if (isout)
                    //    plans = context.sp_getPlanready().ToList();
                    plans = context.sp_planquery(wherestr + "and  plan_status=" + (int)PlanStatus.pending).ToList();
                else
                    plans = context.sp_planquery(wherestr).ToList();





                foreach (var plan in plans)
                {
                    var newplan = new PlanInfo();

                    newplan.checkstatus = (PlanStatus)plan.plan_status;
                    newplan.formula_id = plan.formula_id.HasValue ? plan.formula_id.Value : 0;

                    newplan.plan_check_by = plan.plan_check_by.HasValue ? plan.plan_check_by.Value : 0;
                    newplan.plan_check_time = plan.plan_check_time.HasValue
                        ? plan.plan_check_time.Value
                        : DateTime.MinValue;
                    newplan.plan_check_remark = plan.plan_check_remark;


                    newplan.plan_create_by = plan.plan_create_by.HasValue ? plan.plan_create_by.Value : 0;
                    newplan.plan_create_time = plan.plan_create_time.HasValue
                        ? plan.plan_create_time.Value
                        : DateTime.MinValue;
                    newplan.plan_date = plan.plan_date.HasValue ? plan.plan_date.Value : DateTime.Now;
                    newplan.plan_id = plan.plan_id;
                    newplan.plan_times = plan.plan_times.HasValue ? plan.plan_times.Value : 0;

                    newplan.plan_update_by = plan.plan_update_by.HasValue ? plan.plan_update_by.Value : 0;
                    newplan.plan_update_time = plan.plan_update_time.HasValue
                        ? plan.plan_update_time.Value
                        : DateTime.MinValue;


                    newplan.checkstatus = plan.plan_status.HasValue
                        ? (PlanStatus)plan.plan_status.Value
                        : PlanStatus.draft;


                    newplan.plan_check_by = plan.plan_check_by.HasValue ? plan.plan_check_by.Value : 0;
                    newplan.plan_check_time = plan.plan_check_time.HasValue
                        ? plan.plan_check_time.Value
                        : DateTime.MinValue;


                    newplan.plan_IsGenerateResources = plan.plan_IsGenerateResources.HasValue
                        ? plan.plan_IsGenerateResources.Value
                        : false;

                    newplan.plan_isout = plan.plan_OutId.HasValue ? true : false;

                    res.Add(newplan);
                }
                return res;
            }
        }


        public static List<PlanInfo> GetPlansByOutId(int OutId)
        {
            using (var context = new Entities())
            {
                var res = new List<PlanInfo>();
                var plans = context.plans.Where(a => a.plan_OutId == OutId).ToList();
                foreach (var plan in plans)
                {
                    var newplan = new PlanInfo();

                    newplan.checkstatus = (PlanStatus)plan.plan_status;
                    newplan.formula_id = plan.formula_id.HasValue ? plan.formula_id.Value : 0;

                    newplan.plan_check_by = plan.plan_check_by.HasValue ? plan.plan_check_by.Value : 0;
                    newplan.plan_check_time = plan.plan_check_time.HasValue
                        ? plan.plan_check_time.Value
                        : DateTime.MinValue;
                    newplan.plan_check_remark = plan.plan_check_remark;


                    newplan.plan_create_by = plan.plan_create_by.HasValue ? plan.plan_create_by.Value : 0;
                    newplan.plan_create_time = plan.plan_create_time.HasValue
                        ? plan.plan_create_time.Value
                        : DateTime.MinValue;

                    newplan.plan_date = plan.plan_date.HasValue ? plan.plan_date.Value : DateTime.Now;
                    newplan.plan_id = plan.plan_id;
                    newplan.plan_times = plan.plan_times.HasValue ? plan.plan_times.Value : 0;

                    newplan.plan_update_by = plan.plan_update_by.HasValue ? plan.plan_update_by.Value : 0;
                    newplan.plan_update_time = plan.plan_update_time.HasValue
                        ? plan.plan_update_time.Value
                        : DateTime.MinValue;


                    newplan.checkstatus = plan.plan_status.HasValue
                        ? (PlanStatus)plan.plan_status.Value
                        : PlanStatus.draft;

                    newplan.plan_IsGenerateResources = plan.plan_IsGenerateResources.HasValue
                        ? plan.plan_IsGenerateResources.Value
                        : false;

                    res.Add(newplan);
                }
                return res;
            }
        }


        public static bool UpdatePlan(PlanInfo planinfo)
        {
            using (var context = new Entities())
            {
                var newplan = context.plans.FirstOrDefault(a => a.plan_id == planinfo.plan_id);
                if (newplan == null)
                    return false;

                newplan.formula_id = planinfo.plan_id;
                newplan.plan_date = planinfo.plan_date;
                newplan.plan_times = planinfo.plan_times;
                newplan.plan_update_time = planinfo.plan_update_time;
                newplan.plan_update_by = ApplicationData.CurrentUserInfo.UserId;
                newplan.plan_status = (int)PlanStatus.draft;
                newplan.plan_IsGenerateResources = false;

                context.SaveChanges();
                return true;
            }
        }


        public static bool CheckPlan(PlanInfo planinfo)
        {
            using (var context = new Entities())
            {
                var newplan = context.plans.FirstOrDefault(a => a.plan_id == planinfo.plan_id);
                if (newplan == null)
                    return false;

                newplan.plan_IsGenerateResources = false;
                newplan.plan_check_by = ApplicationData.CurrentUserInfo.UserId;
                newplan.plan_check_time = DateTime.Now;
                newplan.plan_check_remark = planinfo.plan_check_remark;

                newplan.plan_status = (int)planinfo.checkstatus;
                context.SaveChanges();
                return true;
            }
        }

        public static int CreatePlanOut(PlanOutInfo info)
        {
            using (var context = new Entities())
            {
                //create a plan-out

                plan_out newplanout = null;

                bool isnew = false; newplanout = context.plan_out.FirstOrDefault(a => a.plan_out_id == info.plan_out_id);
                if (newplanout == null)
                {
                    isnew = true;
                    newplanout = new plan_out
                    {
                        plan_out_create_by = ApplicationData.CurrentUserInfo.UserId,
                        plan_out_create_time = DateTime.Now
                    };
                }
                //  newplanout = new plan_out();
                newplanout.plan_out_code = info.plan_out_code;
                newplanout.plan_isactive = true;
                newplanout.plan_remark = info.plan_remark;

                newplanout.plan_out_update_by = ApplicationData.CurrentUserInfo.UserId;
                newplanout.plan_out_update_time = DateTime.Now;
                newplanout.plan_out_check_status = (int)PlanStatus.draft;
                newplanout.plan_out_date = info.plan_out_date;
                newplanout.plan_produce_date = info.plan_produce_date;
                newplanout.plan_out_get_by = info.plan_out_get_by;



                if (isnew)
                {
                    //只有新增的时候才添加。
                    context.plan_out.AddObject(newplanout);
                }
                //remove the detailes.
                context.ExecuteStoreCommand("delete from  plan_out_detail where plan_out_id=" + newplanout.plan_out_id);
                context.SaveChanges();

                var resources = info.Details;

                foreach (var resource in resources)
                {
                    var newresource = new plan_out_need
                    {
                        resource_id = resource.Key,
                        reource_need_number = resource.Value,
                        plan_out_isactive = true,
                        plan_out_id = newplanout.plan_out_id
                    };

                    context.plan_out_need.AddObject(newresource);
                }
                context.SaveChanges();

                return newplanout.plan_out_id;
            }
        }


        public static int CreatePlanOut(PlanOutInfo info, List<PlanInfo> plans, Dictionary<int, decimal> resources)
        {
            using (var context = new Entities())
            {
                //create a plan-out
                var newplanout = new plan_out
                {
                    plan_out_code = info.plan_out_code,
                    plan_isactive = true,
                    plan_remark = info.plan_remark,
                    plan_out_create_by = ApplicationData.CurrentUserInfo.UserId,
                    plan_out_create_time = DateTime.Now,
                    plan_out_update_by = ApplicationData.CurrentUserInfo.UserId,
                    plan_out_update_time = DateTime.Now,
                    plan_out_check_status = (int)PlanStatus.draft,
                    plan_out_date = info.plan_out_date,
                    plan_produce_date = info.plan_produce_date
                };


                newplanout.plan_out_update_by = 0;
                newplanout.plan_out_update_time = DateTime.Now;

                context.plan_out.AddObject(newplanout);
                context.SaveChanges();

                //update the plan out id
                foreach (var plan in plans)
                {
                    var findplan = context.plans.FirstOrDefault(a => a.plan_id == plan.plan_id);
                    if (findplan != null)
                    {
                        findplan.plan_IsGenerateResources = true;
                        findplan.plan_OutId = newplanout.plan_out_id;
                    }
                }
                context.SaveChanges();

                //需求数量 
                foreach (var resource in resources)
                {
                    var newresource = new plan_out_need();
                    newresource.resource_id = resource.Key;
                    newresource.reource_need_number = resource.Value;
                    newresource.plan_out_isactive = true;
                    newresource.plan_out_id = newplanout.plan_out_id;

                    context.plan_out_need.AddObject(newresource);
                }
                context.SaveChanges();

                return newplanout.plan_out_id;

            }
        }

        public static bool CheckPlanOuts(PlanOutInfo info)
        {
            using (var context = new Entities())
            {
                var findplan = context.plan_out.FirstOrDefault(a => a.plan_out_id == info.plan_out_id);
                if (findplan == null)
                    return false;

                findplan.plan_out_check_status = (int)info.plan_out_check_status;
                findplan.plan_out_check_by = ApplicationData.CurrentUserInfo.UserId;
                findplan.plan_out_check_time = DateTime.Now;
                findplan.plan_out_check_remark = info.plan_out_check_remark;
                context.SaveChanges();

                return true;
            }
        }



        public static List<PlanOutInfo> GetPlanOuts(bool isouted = false)
        {
            using (var context = new Entities())
            {

                var outs = context.plan_out.ToList();

                if (isouted)
                    outs = outs.Where(a => a.plan_isout == true).ToList();

                var res = new List<PlanOutInfo>();

                foreach (var outinfo in outs)
                {
                    var planout = new PlanOutInfo();
                    planout.plan_out_id = outinfo.plan_out_id;
                    planout.plan_out_code = outinfo.plan_out_code;
                    planout.plan_produce_date = outinfo.plan_produce_date.HasValue
                        ? outinfo.plan_produce_date.Value
                        : DateTime.MinValue;

                    planout.plan_out_date = outinfo.plan_out_date.HasValue
                        ? outinfo.plan_out_date.Value
                        : DateTime.MinValue;

                    planout.plan_isactive = outinfo.plan_isactive.HasValue ?
                        outinfo.plan_isactive.Value : false;

                    planout.plan_remark = outinfo.plan_remark;

                    planout.plan_out_create_by = outinfo.plan_out_create_by.HasValue
                        ? outinfo.plan_out_create_by.Value
                        : 0;

                    planout.plan_out_create_time = outinfo.plan_out_create_time.HasValue
                        ? outinfo.plan_out_create_time.Value
                        : DateTime.MinValue;

                    planout.plan_out_update_by = outinfo.plan_out_update_by.HasValue
                        ? outinfo.plan_out_update_by.Value
                        : 0;
                    planout.plan_out_update_time = outinfo.plan_out_update_time.HasValue
                        ? outinfo.plan_out_update_time.Value
                        : DateTime.MinValue;

                    planout.plan_out_check_status = outinfo.plan_out_check_status.HasValue
                        ? (CheckStatus)outinfo.plan_out_check_status.Value
                        : CheckStatus.Pending;

                    planout.plan_out_check_by = outinfo.plan_out_check_by.HasValue
                        ? outinfo.plan_out_check_by.Value
                        : 0;
                    planout.plan_out_check_time = outinfo.plan_out_check_time.HasValue
                        ? outinfo.plan_out_check_time.Value
                        : DateTime.MinValue;

                    planout.plan_out_check_remark = outinfo.plan_out_check_remark;
                    planout.plan_out_get_by = outinfo.plan_out_get_by.HasValue
                        ? outinfo.plan_out_get_by.Value
                        : 0;

                    planout.plan_out_get_time = outinfo.plan_out_get_time.HasValue
                        ? outinfo.plan_out_get_time.Value
                        : DateTime.MinValue;
                    planout.plan_isout = outinfo.plan_isout.HasValue ? outinfo.plan_isout.Value : false;


                    planout.Details = new Dictionary<int, decimal>();
                    var details = context.plan_out_need.Where(a => a.plan_out_id == planout.plan_out_id);
                    foreach (var detail in details)
                    {
                        if (planout.Details.ContainsKey(detail.resource_id.Value))
                        {
                            planout.Details[detail.resource_id.Value] = planout.Details[detail.resource_id.Value] +
                                                                        detail.reource_need_number.Value;
                        }
                        else
                            planout.Details.Add(detail.resource_id.Value, detail.reource_need_number.Value);


                    }
                    res.Add(planout);
                }
                return res;

            }
        }

        public static Dictionary<int, decimal> GetPlanNeeded(int out_id)
        {
            using (var context = new Entities())
            {
                var res = new Dictionary<int, decimal>();
                var needed = context.plan_out_need.Where(a => a.plan_out_id == out_id).ToList();

                foreach (var need in needed)
                {
                    if (res.ContainsKey(need.resource_id.Value))
                    {
                        res[need.resource_id.Value] =
                            (decimal)(res[need.resource_id.Value] + need.reource_need_number.Value);
                    }
                    else
                        res.Add(need.resource_id.Value, need.reource_need_number.Value);
                }
                return res;
            }
        }

        public static bool CreateStorageOutData(PlanOutInfo planout, List<int> detailIds)
        {
            using (var context = new Entities())
            {
                foreach (var id in detailIds)
                {
                    var findresouse = context.supply_detail.FirstOrDefault(a => a.supply_detail_id == id);
                    if (findresouse == null)
                    {
                        return false;
                    }
                    findresouse.supply_isInProducing = true;//转入生产库存

                    var newout = new plan_out_detail { plan_out_detail_isactive = true }; newout.supply_detail_id = id;
                    newout.plan_out_id = planout.plan_out_id;
                    context.plan_out_detail.AddObject(newout);
                }

                var findout = context.plan_out.FirstOrDefault(a => a.plan_out_id == planout.plan_out_id);
                if (findout == null)
                    return false;

                findout.plan_isout = true;
                findout.plan_out_get_by = planout.plan_out_get_by;
                findout.plan_out_get_time = planout.plan_out_get_time;

                context.SaveChanges();
                return true;
            }
        }

        public static bool CreateStorageOutData(ResourceOutInfo outinfo, List<int> detailIds)
        {
            using (var context = new Entities())
            {
                foreach (var id in detailIds)
                {
                    var findresouse = context.supply_detail.FirstOrDefault(a => a.supply_detail_id == id);
                    if (findresouse == null)
                    {
                        return false;
                    }
                    findresouse.supply_isInProducing = true;//转入生产库存

                    var newout = new plan_out_detail { plan_out_detail_isactive = true }; newout.supply_detail_id = id;
                    newout.plan_out_id = outinfo.resource_out_id;
                    context.plan_out_detail.AddObject(newout);


                    var newoutinfo = new resource_out_detail();
                    newoutinfo.resource_out_id = outinfo.resource_out_id;
                    newoutinfo.supply_detail_id = id;
                    context.resource_out_detail.AddObject(newoutinfo);
                }

                var findout = context.resource_out.FirstOrDefault(a => a.resource_out_id == outinfo.resource_out_id);
                if (findout == null)
                    return false;

                //findout.plan_isout = true;
                //findout.plan_out_get_by = planout.plan_out_get_by;
                //findout.plan_out_get_time = planout.plan_out_get_time;
                findout.resource_status = 10;

                context.SaveChanges();
                return true;
            }
        }

        public static bool RemovePlan(PlanInfo plan)
        {
            using (var context = new Entities())
            {
                var findplan = context.plans.FirstOrDefault(a => a.plan_id == plan.plan_id);
                if (findplan == null)
                    return false;

                findplan.plan_status = (int)PlanStatus.deleted;
                context.SaveChanges();
                return true;
            }

        }



        public static bool StartToExecutePlan(PlanInfo plan)
        {
            using (var context = new Entities())
            {

                var findplan = context.plans.FirstOrDefault(a => a.plan_id == plan.plan_id);
                if (findplan == null)
                    return false;

                //进行中...
                findplan.plan_status = (int)PlanStatus.pending;


                for (int i = 0; i < plan.plan_times; i++)
                {
                    var newdetail = new plan_detail();
                    newdetail.plan_id = plan.plan_id;
                    newdetail.plan_detail_isactive = true;
                    newdetail.plan_create_by = 0;
                    newdetail.plan_create_time = DateTime.Now;
                    newdetail.plan_detail_status = (int)PlanStatus.pending;
                    context.plan_detail.AddObject(newdetail);
                }



                context.SaveChanges();
                return true;
            }
        }



        public static List<plan_detail_info> GetPlanDetails(PlanInfo plan)
        {
            using (var context = new Entities())
            {
                var details = new List<plan_detail_info>();
                var detailsIndb = context.plan_detail.Where(a => a.plan_id == plan.plan_id).ToList();
                foreach (var detail in detailsIndb)
                {
                    var newdetail = new plan_detail_info();
                    newdetail.plan_create_by = detail.plan_create_by.HasValue ? detail.plan_create_by.Value : 0;
                    newdetail.plan_create_time = detail.plan_create_time.HasValue ? detail.plan_create_time.Value : DateTime.MinValue;
                    newdetail.plan_detail_end_time = detail.plan_detail_end_time;
                    newdetail.plan_detail_id = detail.plan_detail_id;
                    newdetail.plan_detail_isactive = detail.plan_detail_isactive.HasValue ? detail.plan_detail_isactive.Value : false;
                    newdetail.plan_detail_start_time = detail.plan_detail_start_time;
                    newdetail.plan_detail_status = (PlanStatus)detail.plan_detail_status;
                    newdetail.plan_id = detail.plan_id.HasValue ? detail.plan_id.Value : 0;

                    details.Add(newdetail);
                }
                return details;
            }
        }

        public static plan_detail_info GetUNFinishedPlanDetail(PlanInfo plan)
        {
            using (var context = new Entities())
            {
                var plandetail = new plan_detail();
                //find the first plane details.
                plandetail = context.plan_detail.OrderBy(a => a.plan_detail_id).FirstOrDefault(a => a.plan_id == plan.plan_id && a.plan_detail_status == (int)PlanStatus.pending);

                if (plandetail == null)
                    return null;

                plandetail.plan_detail_status = (int)PlanStatus.working;
                context.SaveChanges();


                var res = new plan_detail_info();
                res.plan_create_by = plandetail.plan_create_by.HasValue ? plandetail.plan_create_by.Value : 0;
                res.plan_create_time = plandetail.plan_create_time.HasValue ? plandetail.plan_create_time.Value : DateTime.MinValue;
                res.plan_detail_end_time = plandetail.plan_detail_end_time.HasValue ? plandetail.plan_detail_end_time.Value : DateTime.MinValue;
                res.plan_detail_id = plandetail.plan_detail_id;
                res.plan_detail_isactive = plandetail.plan_detail_isactive.HasValue ? plandetail.plan_detail_isactive.Value : false;
                res.plan_detail_start_time = plandetail.plan_detail_start_time.HasValue ? plandetail.plan_detail_start_time.Value : DateTime.MinValue;

                res.plan_detail_status = plandetail.plan_detail_status.HasValue ? (PlanStatus)plandetail.plan_detail_status.Value : PlanStatus.pending;
                res.plan_id = plandetail.plan_id.HasValue ? plandetail.plan_id.Value : 0;
                return res;
            }
        }


        public static bool UpdatePlanStatus(int planId)
        {
            using (var context = new Entities())
            {
                var findplan = context.plans.FirstOrDefault(a => a.plan_id == planId);
                if (findplan == null)
                    return false;


                var finddetails = context.plan_detail.Where(a => a.plan_id == planId
                    &&

                    (a.plan_detail_status == (int)PlanStatus.suspend
                    || a.plan_detail_status == (int)PlanStatus.pending || a.plan_detail_status == (int)PlanStatus.working
                    || a.plan_detail_status == (int)PlanStatus.pause
                    ));

                //如果没有等待的了.意味着都完成了.


                if (finddetails.Count() == 0)
                {
                    findplan.plan_status = (int)PlanStatus.done;
                    context.SaveChanges();
                    return true;
                }
                else
                {
                    return false;
                }

            }
        }

        public static List<plan_detail_step_info> GetPlanDetailSteps(plan_detail_info detail)
        {
            using (var context = new Entities())
            {
                var steps = context.plan_detail_step.Where(a => a.plan_detail_id == detail.plan_detail_id).ToList();
                if (steps.Count == 0)
                {
                    context.ExecuteStoreCommand(string.Format("exec  sp_createplan_steps {0}", detail.plan_detail_id));
                    context.SaveChanges();
                }
                steps = context.plan_detail_step.Where(a => a.plan_detail_id == detail.plan_detail_id).ToList();
                var res = new List<plan_detail_step_info>();

                foreach (var step in steps)
                {
                    var newstep = new plan_detail_step_info();
                    newstep.plan_detail_step_id = step.plan_detail_step_id;
                    newstep.plan_detail_id = step.plan_detail_id;
                    newstep.plan_detail_step_order = step.plan_detail_step_order.HasValue ? step.plan_detail_step_order.Value : 0;
                    newstep.plan_detail_step_status = step.plan_detail_step_status.HasValue ? step.plan_detail_step_status.Value : 10;// the default value is pending.
                    newstep.plan_detail_end_date = step.plan_detail_end_date.HasValue ? step.plan_detail_end_date.Value : DateTime.MinValue;
                    newstep.plan_detail_step_user_id = step.plan_detail_step_user_id.HasValue ? step.plan_detail_step_user_id.Value : 0;
                    newstep.plan_detail_step_isactive = step.plan_detail_step_isactive.HasValue ? step.plan_detail_step_isactive.Value : true;
                    newstep.resource_id = step.resource_id.HasValue ? step.resource_id.Value : 0;
                    newstep.resource_ischangecar = step.resource_changecar.HasValue ? step.resource_changecar.Value : false;
                    newstep.resource_car_number = step.resource_car_number.HasValue ? step.resource_car_number.Value : 1;
                    newstep.resource_need = step.resource_need.HasValue ? step.resource_need.Value : 0;

                    res.Add(newstep);
                }
                return res;
            }


        }



        public static bool CancelPlanDetail(int plan_detail_id, PlanStatus status)
        {
            using (var context = new Entities())
            {
                var plan_detail = context.plan_detail.FirstOrDefault(a => a.plan_detail_id == plan_detail_id);
                if (plan_detail == null)
                    return false;

                plan_detail.plan_detail_status = (int)status;
                context.SaveChanges();
                return true;
            }
        }

       


    }
}
